package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.domain.Destination;
import cn.wolfcode.luowowo.domain.Travel;
import cn.wolfcode.luowowo.domain.UserInfo;
import cn.wolfcode.luowowo.query.TravelCondition;
import cn.wolfcode.luowowo.query.TravelQuery;
import cn.wolfcode.luowowo.repository.TravelRepository;
import cn.wolfcode.luowowo.service.IDestinationService;
import cn.wolfcode.luowowo.service.ITravelService;
import cn.wolfcode.luowowo.service.IUserInfoService;
import cn.wolfcode.luowowo.util.DBHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.jws.Oneway;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import static cn.wolfcode.luowowo.domain.Travel.*;

//旅游服务接口实现类
@Service
//@Transactional
public class TravelServiceImpl implements ITravelService {
    //注入旅游接口
    @Autowired
    private TravelRepository travelRepository;
    //注入用于分页的接口
    @Autowired
    private MongoTemplate mongoTemplate;
    //注入用户服务接口
    @Autowired
    private IUserInfoService userInfoService;
    //注入目的地服务接口
    @Autowired
    private IDestinationService destinationService;

    //更新或修改
    @Override
    public void saveOrUpdate(Travel travel) {
        //目的地名称
        Destination destination = destinationService.get(travel.getDestId());
        travel.setDestName(destination.getName());
        //当前登录用户id
        //最后更新时间
        travel.setLastUpdateTime(new Date());
        //发布时间
        travel.setReleaseTime(new Date());
        //如果有id就更新
        if (StringUtils.hasLength(travel.getId())) {
            travelRepository.save(travel);
        } else {
            //设置id为空
            travel.setId(null);
            //创建时间
            travel.setCreateTime(new Date());
            travelRepository.save(travel);
        }
    }

    //删除
    @Override
    public void delete(String id) {
        travelRepository.deleteById(id);
    }

    //获取单个
    @Override
    public Travel get(String id) {
        Optional<Travel> op = travelRepository.findById(id);
        if (op.isPresent()){
            Travel travel = op.get();
            //根据作者id将用户对象查询出来设置到游记中
            UserInfo userInfo = userInfoService.get(travel.getUserId());
            travel.setAuthor(userInfo);
            //根据目的地id将目的地查询出来设置到游记的忽略字段中
            Destination destination = destinationService.get(travel.getDestId());
            travel.setDest(destination);
            return travel;
        }
        return null;
    }

    //获取全部
    @Override
    public List<Travel> listAll() {
        return travelRepository.findAll();
    }

    //分页
    @Override
    public Page<Travel> query(TravelQuery qo) {
        //创建查询条件
        Query query = new Query();
        //创建排序条件字段
        String sort = "_id";

        //添加限制目的地条件
        if (StringUtils.hasLength(qo.getDestId())) {
            query.addCriteria(Criteria.where("destId").is(qo.getDestId()));
        }
        //添加是否最新最热条件
        //如果orderType有值就添加条件
        if (qo.getOrderType() != null) {
            //如果orderType为1就添加条件根据更新时间排序，排倒序
            if (qo.getOrderType() == TravelQuery.NEW_DAY) {
                sort = "lastUpdateTime";
                //如果orderType为2就添加条件根据点击阅读数排序，排倒序
            } else if (qo.getOrderType() == TravelQuery.HOT_DATA) {
                sort = "viewnum";
            }
        }
        //旅游消费条件
        TravelCondition money = qo.getMoney();
        //添加消费限制条件
        if (money != null) {
            query.addCriteria(Criteria.where("perExpend").gte(money.getMin()).lte(money.getMax()));
        }

        //旅游天数条件
        TravelCondition day = qo.getDay();
        //添加天数条件
        if (day != null) {
            query.addCriteria(Criteria.where("day").gte(day.getMin()).lte(day.getMax()));
        }
        //分页条件
        Pageable pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.DESC, sort);
        //根据关联目的地查询
        Page<Travel> page = DBHelper.query(mongoTemplate, Travel.class, query, pageable);
        for (Travel travel : page) {
            travel.setAuthor(userInfoService.get(travel.getUserId()));
        }
        return page;
    }

    //审核通过或审核不通过或下架
    @Override
    public void changeState(String id, int state) {
        //先判断游记是否存在或是否待审核状态
        Travel travel = this.get(id);
        if (travel == null || travel.getState() == STATE_WAITING) {
            //如果是审核通过
            if (state == STATE_RELEASE) {
                //就更改为发布状态
                travel.setState(state);
                //并且更改发布时间
                travel.setReleaseTime(new Date());
                //更改最新更改时间
                travel.setLastUpdateTime(new Date());
            }
            //如果是审核拒绝
            if (state == STATE_REJECT) {
                //就更改为拒绝状态
                travel.setState(state);
                //更改最新更改时间
                travel.setLastUpdateTime(new Date());
            }
            travelRepository.save(travel);
        }
        //判断是否下架操作
        if (state == STATE_NORMAL) {
            //如果是下架就改为还在编辑的状态
            travel.setState(state);
            //然后更新最新更新时间
            travel.setLastUpdateTime(new Date());
            //然后更新
            travelRepository.save(travel);
        }
    }

    public List<Travel> getViewnumTop3(String destId) {
        //点击量前3
        Pageable of = PageRequest.of(0, 3, Sort.Direction.DESC, "viewnum");
        return travelRepository.findByDestId(destId, of);
    }
    @Override
    public List<Travel> list() {
        return travelRepository.findAll();
    }

    @Override
    public List<Travel> findByDestName(String destName) {
        List<Travel> list = travelRepository.findByDestName(destName);
        for (Travel travel : list) {
            //用户信息
            travel.setAuthor(userInfoService.get(travel.getUserId()));
        }
        return list;
    }
}
